package com.acme.bankapp.service.bank;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.StringTokenizer;

import com.acme.bankapp.domain.bank.Account;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.CheckingAccount;
import com.acme.bankapp.domain.bank.Client;
import com.acme.bankapp.domain.bank.Gender;
import com.acme.bankapp.domain.bank.SavingsAccount;
import com.acme.bankapp.domain.bank.exceptions.ClientAlreadyExistsException;

public class BankFeederService {

	private static final String ERROR_READING_FILE = "Error reading file";
	private static final String FEED_FILE_CONTAINS_REPEATED_CLIENTS = "Feed file contains repeated clients";

	public static Bank readBank(final Bank bank, String fileName) {
		try (RandomAccessFile inputFile = new RandomAccessFile(fileName, "r");) {
			String line = ""; 
			
			try {
				while ((line = inputFile.readLine()) != null) {
					bank.addClient(makeClientFromString(line));
				}
			} catch (ClientAlreadyExistsException e) {
				System.out.println(FEED_FILE_CONTAINS_REPEATED_CLIENTS);
			}
		} catch (IOException e) {
			System.out.println(ERROR_READING_FILE);
		}
		return bank;
	}

	public static Client makeClientFromString(final String str) {
		
		class ClientAccountPair {
			Account acc = null;
			double bal = 0, overdraft = 0;
			String name = "";
			Gender gender = Gender.MALE;
			boolean isChecking = false;
			
			Client makeClientObject() {
				if (isChecking) {
					acc = new CheckingAccount(bal, overdraft);
				} else {
					acc = new SavingsAccount(bal);
				}
				return new Client(name,gender,acc);
			}
		}

		ClientAccountPair clAccPair = new ClientAccountPair();
		StringTokenizer fullStrTok;
		System.out.println(str);
		if (str == null) {
			return null;
		}
		
		fullStrTok = new StringTokenizer(str, ";");
		
		while (fullStrTok.hasMoreTokens()) {
			StringTokenizer sumStrTok = new StringTokenizer(fullStrTok.nextToken(), "=");
			switch (sumStrTok.nextToken()) {
			case "accounttype":
				clAccPair.isChecking = "c".equals(sumStrTok.nextToken());
				break;
			case "balance":
				clAccPair.bal = Double.parseDouble(sumStrTok.nextToken());
				break;
			case "overdraft":
				clAccPair.overdraft = Double.parseDouble(sumStrTok.nextToken());
				break;
			case "name":
				clAccPair.name = sumStrTok.nextToken();
				break;
			case "gender":
				clAccPair.gender = "f".equals(sumStrTok.nextToken()) ? Gender.FEMALE : Gender.MALE;
				break;
			default:
				break;
			}
		}
		
		return clAccPair.makeClientObject();
	}
}
